package com.globalwave.rule.engine.example;

import java.sql.Types;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.junit.Assert;
import org.junit.Test;

import com.globalwave.rule.engine.RuleTree;
import com.globalwave.rule.engine.operator.OperatorInf;
import com.globalwave.rule.entity.RuleAction;
import com.globalwave.rule.entity.RuleLimit;

public class RuleTreeTest {

	@Test
	public void evaluate() throws Exception {
		List<RuleLimit> limits = new ArrayList<RuleLimit>() ;
		
		RuleLimit limit = getInt100Limit() ;
		limits.add(limit) ;
		
		Map<String, Object> vars = new HashMap<String, Object>() ;
		TestObj obj = new TestObj() ;
		obj.setIntValue(100) ;
		vars.put("obj", obj) ;
		
		Assert.assertTrue(new RuleTree().build(limits, null).evaluate(vars)) ;
		
		obj.setIntValue(101) ;

		Assert.assertFalse(new RuleTree().build(limits, null).evaluate(vars)) ;
		
		obj.setIntValue(-1) ;
		obj.setDblValue(100d) ;
		
		limit.setL_property("obj.dblValue") ;
		limit.setType_(Types.DOUBLE) ;

		Assert.assertTrue(new RuleTree().build(limits, null).evaluate(vars)) ;

		
		obj.setDblValue(101d) ;

		Assert.assertFalse(new RuleTree().build(limits, null).evaluate(vars)) ;
	}
	

	@Test
	public void action() throws Exception {
		List<RuleLimit> limits = new ArrayList<RuleLimit>() ;
		
		RuleLimit limit = getInt100Limit() ;
		limits.add(limit) ;

		List<RuleAction> actions = new ArrayList<RuleAction>() ;
		
		RuleAction action = new RuleAction() ;
		actions.add(action) ;
		
		action.setVar_property("obj.strValue") ;
		action.setType_(Types.VARCHAR) ;
		action.setValue_value("OK.") ;
		
		Map<String, Object> vars = new HashMap<String, Object>() ;
		TestObj obj = new TestObj() ;
		obj.setIntValue(100) ;
		vars.put("obj", obj) ;
		
		RuleTree tree = new RuleTree() ;
		
		tree.build(limits, actions).trigger(vars) ;
		//tree.handleResult(vars) ;
		
		Assert.assertEquals("OK.", obj.getStrValue()) ;
		
		obj.setIntValue(101) ;
		obj.setStrValue(null) ;
		
		tree.build(limits, actions).trigger(vars) ;
		//tree.handleResult(vars) ;
		
		Assert.assertEquals(null, obj.getStrValue()) ;
	}
	
	private RuleLimit getInt100Limit() {
		RuleLimit limit = new RuleLimit() ;
		
		limit.setId(1000L) ;
		limit.setPro_limit_node_id(RuleTree.rootId) ;
		limit.setL_property("obj.intValue") ;
		limit.setOperator_(OperatorInf.OPERATOR_CD_EQ) ;
		limit.setR_value("100") ;
		limit.setType_(Types.INTEGER) ;
		
		return limit ;
	}
	
	public class TestObj {
		private int intValue ;
		private double dblValue ;
		private String strValue ;
		
		public int getIntValue() {
			return intValue;
		}
		public void setIntValue(int intValue) {
			this.intValue = intValue;
		}
		public double getDblValue() {
			return dblValue;
		}
		public void setDblValue(double dblValue) {
			this.dblValue = dblValue;
		}
		public String getStrValue() {
			return strValue;
		}
		public void setStrValue(String strValue) {
			this.strValue = strValue;
		}
		
	}
}
